﻿package com.gengine.resource
{
    import com.gengine.core.call.*;
    import com.gengine.debug.*;
    import com.gengine.global.*;
    import com.gengine.resource.info.*;
    import com.gengine.resource.loader.*;
    import flash.events.*;
    import flash.net.*;

    public class PreLoaderManager extends EventDispatcher
    {
        private var _urlLoader:URLLoader;
        private var _isLoading:Boolean = false;
        private var _completeCaller:Caller;
        private var _errorCaller:Caller;
        private var _currentResInfo:ResourceInfo;
        private var _queueArray:Array;
        private static var _instance:PreLoaderManager = new PreLoaderManager;

        public function PreLoaderManager()
        {
            if (_instance != null)
            {
                throw new Error("LoaderManager 单例  ");
            }
            this._queueArray = [];
            this._completeCaller = new Caller();
            this._errorCaller = new Caller();
            this._urlLoader = new URLLoader();
            return;
        }// end function

        public function start() : void
        {
            this.loadNext();
            return;
        }// end function

        public function preLoad(param1:String, param2:Object = null) : void
        {
            var _loc_3:* = ResourceManager.getInfoByName(param1);
            if (_loc_3 == null)
            {
                Log.error(param1 + "==没有该文件");
                return;
            }
            if (param2)
            {
                _loc_3.extData = param2;
            }
            if (_loc_3.isLoaded || _loc_3.isLoading || _loc_3.isAddToPreLoad)
            {
                return;
            }
            this.addQueue(_loc_3);
            return;
        }// end function

        private function loadResource(param1:ResourceInfo) : Boolean
        {
            if (!LoaderManager.instance.isLoading() && !this._isLoading)
            {
                this._isLoading = true;
                param1.isPreLoading = true;
                this._currentResInfo = param1;
                this._urlLoader.dataFormat = URLLoaderDataFormat.BINARY;
                this._urlLoader.addEventListener(Event.COMPLETE, this.onCompleteHandler);
                this._urlLoader.addEventListener(ProgressEvent.PROGRESS, this.onProgressHandler);
                this._urlLoader.addEventListener(IOErrorEvent.IO_ERROR, this.onIOError);
                this._urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onIOError);
                this._urlLoader.load(new URLRequest(param1.path));
                return true;
            }
            return false;
        }// end function

        private function addQueue(param1:ResourceInfo) : void
        {
            param1.isAddToPreLoad = true;
            if (this.loadResource(param1) == false)
            {
                this._queueArray.push(param1);
            }
            return;
        }// end function

        protected function loadNext() : void
        {
            var _loc_1:ResourceInfo = null;
            if (this._queueArray.length > 0)
            {
                _loc_1 = this._queueArray[0] as ResourceInfo;
                if (_loc_1.isLoaded || _loc_1.isLoading)
                {
                    this._queueArray.shift();
                    this.loadNext();
                }
                else if (this.loadResource(_loc_1))
                {
                    this._queueArray.shift();
                }
            }
            return;
        }// end function

        protected function onCompleteHandler(event:Event) : void
        {
            try
            {
                this._urlLoader.removeEventListener(Event.COMPLETE, this.onCompleteHandler);
                this._urlLoader.removeEventListener(ProgressEvent.PROGRESS, this.onProgressHandler);
                this._urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, this.onIOError);
                this._urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onIOError);
                this._urlLoader.close();
            }
            catch (e:Error)
            {
            }
            if (this._currentResInfo)
            {
                this._currentResInfo.cacheBytes = event.target.data;
            }
            this._isLoading = false;
            this._currentResInfo.isPreLoading = false;
            this._completeCaller.call(this._currentResInfo.name);
            this.loadNext();
            return;
        }// end function

        protected function onProgressHandler(event:ProgressEvent) : void
        {
            dispatchEvent(event);
            return;
        }// end function

        private function onIOError(event:ErrorEvent) : void
        {
            this._urlLoader.removeEventListener(Event.COMPLETE, this.onCompleteHandler);
            this._urlLoader.removeEventListener(ProgressEvent.PROGRESS, this.onProgressHandler);
            this._urlLoader.removeEventListener(IOErrorEvent.IO_ERROR, this.onIOError);
            this._urlLoader.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, this.onIOError);
            this.onIOErrorHandler(event);
            this._currentResInfo.isPreLoading = false;
            this._errorCaller.call(this._currentResInfo.name);
            this.loadNext();
            return;
        }// end function

        protected function onIOErrorHandler(event:ErrorEvent) : void
        {
            Log.system(event.text);
            if (Global.isDebugModle)
            {
                dispatchEvent(new LoaderErrorEvent(event.text));
            }
            return;
        }// end function

        public function addLoadedCall(param1:String, param2:Function) : void
        {
            this._completeCaller.addCall(param1, param2);
            return;
        }// end function

        public function addErrorCall(param1:String, param2:Function) : void
        {
            this._errorCaller.addCall(param1, param2);
            return;
        }// end function

        public function get preloadingInfo() : ResourceInfo
        {
            if (this._currentResInfo && this._currentResInfo.isPreLoading)
            {
                return this._currentResInfo;
            }
            return null;
        }// end function

        public static function get instance() : PreLoaderManager
        {
            return _instance;
        }// end function

    }
}
